package nucleo;

import java.applet.Applet;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 *
 * @author OsomGames
 * @date 18-07-2011
 */
public class Personaje extends Elemento {
    // Array que contiene los sprites e Integer que señala al actual
    private BufferedImage[] sprites;
    private Integer sprite_actual = 0;
    
    // Objeto para el tratamiento de los sprites
    private Sprite s = new Sprite();
    
    // Constantes de ancho y alto del personaje
    private final int ANCHO;
    private final int ALTO;
    
    // Comprobaciones de si esta andando a izquierda o derecha o si esta en el
    // suelo
    private boolean izquierda, derecha, suelo;
    
    // La zona actual donde esta el personaje
    private Zona zonaActual = null;
    
    // Constante de velocidad del personaje cuando Anda
    private final int VELOCIDAD = 5;
    
    // Puntos utiles para la colision
    // Son los puntos esquina superior izquierda y derecha del personaje
    private Point posicion_punto_izq;
    private Point posicion_punto_der;

    /**
     * Menudo constructor que me acabo de montar chaval, que asco me da
     * @param ruta  - Ruta del fichero
     * @param x     - Posicion X
     * @param y     - Posicion Y
     * @param ancho - Ancho
     * @param alto  - Alto
     * @param filas - Numero de filas
     * @param columnas - Numero de columnas
     * @param a - El Applet al que esta enlazado
     * @param g - Gravedad
     */
    public Personaje(String ruta, int x, int y, int ancho, int alto, int filas, int columnas) {
        // Llamada al constructor padre: Elemento
        super(x, y);

        ANCHO = ancho;
        ALTO = alto;
        this.posicion_punto_izq = new Point(x / ANCHO, y / ALTO);
        this.posicion_punto_der = new Point((x + ANCHO) / ANCHO, y / ALTO);


        izquierda = derecha = suelo = false;

        try {
            sprites = Sprite.cargaSprites(ruta, filas, columnas, ancho, alto);

        } catch (IOException ex) {
            System.out.println("Fallo al separar el sprite" + ex.getMessage());

        }
    }

    /**
     * El metodo para pintar el personaje
     * @param g Graficos 2D
     * @param a El applet al que se pinta
     */
    public void pintarPersonaje(Graphics2D g, Applet a) {
        g.drawImage(sprites[sprite_actual], this.getX(), this.getY(), a);
    }

    /**
     * Añade al personaje en una zona
     * @param queZona La zona a la que se va a añadir
     */
    public void añadirAZona(Zona queZona) {
        zonaActual = queZona;
        zonaActual.añadirPersonaje("Jugador", this);
    }

    /**
     * El metodo que recibe el evento y mueve al personaje
     * @param m - Movimiento
     */
    public void mover(Movimiento m) {
        //AQUI SE VA A LIAR PARDA
        // Avanza a la derecha
        if (m == Movimiento.DERECHA) {
            // ¿Esta libre la derecha?
            this.derecha = true;

        } // Avanza a la izquierda
        else if (m == Movimiento.IZQUIERDA) {
            // ¿Esta libre la izquierda?
            this.izquierda = true;
        }
        if (m == Movimiento.ESPACIO) {
            // Salta
            if (suelo) {
                suelo = false;
            }
        }
    }

    /**
     * Cuando el usuario suelta una tecla de movimiento el personaje se detiene
     * @param m - Movimiento
     */
    public void detenerMover(Movimiento m) {
        if (m == Movimiento.DERECHA) {
            // Detiene a la derecha
            this.derecha = false;
            this.setVx(0);
        } else if (m == Movimiento.IZQUIERDA) {
            // Detiene a la izquierda
            this.izquierda = false;
            this.setVx(0);
        }
    }

    /**
     * Actualizar el movimiento del personaje
     */
    public void actualizarMovimiento() {
        // Hay que actualizar en cada momento la posicion de los dos puntos
        this.posicion_punto_izq.setLocation(this.getX() / ANCHO, this.getY() / ALTO);
        this.posicion_punto_der.setLocation((this.getX() + ANCHO) / ANCHO, this.getY() / ALTO);
        
        // Si teclea a la derecha comprueba si puede ir a la derecha
        if (derecha) {
            if (this.zonaActual.getBloque(posicion_punto_izq.y, posicion_punto_izq.x + 1) == null) {
                // Andar a la derecha
                this.setVx(VELOCIDAD);
                this.setX(this.getX() + this.getVx());
            }
        }
        // Si teclea a la izquierda comprueba si puede ir a la izquierda
        if (izquierda) {
            if (this.zonaActual.getBloque(this.posicion_punto_der.y, this.posicion_punto_der.x - 1) == null) {
                // Andar a la izquierda
                this.setVx(-VELOCIDAD);
                this.setX(this.getX() + this.getVx());
            }

        } 
        // Llamamiento al metodo de comprobacion de gravedad y salto
        comprobarSuelo();
    }
    /**
     * Metodo para la comprobacion de la gravedad y salto.
     * Saber si el personaje tiene bloques justo debajo
     */
    private void comprobarSuelo() {
        
        // Comprueba en cada instante si hay un bloque debajo
        if ((this.zonaActual.getBloque(this.posicion_punto_izq.y + 1, this.posicion_punto_izq.x) == null)
        &&(this.zonaActual.getBloque(this.posicion_punto_der.y + 1, this.posicion_punto_der.x) == null)){
            // La caida/salto
            this.setVy(10);
            this.setY(this.getY() + this.getVy());
        } else {
           
            suelo = true;
        }
    }

    public int getANCHO() {
        return ANCHO;
    }

    public int getALTO() {
        return ALTO;
    }
}
